import { Button, Card, Descriptions, Form, Input, InputNumber } from "antd";
import { useEffect, useState } from "react";
import { getIcmpApi, getToken } from "../utils/client";

function PingPanel() {
    const [tmpHostName, setTmpHostName] = useState("");
    const [hostName, setHostName] = useState("");
    const [pkgSize, setPkgSize] = useState(1024);

    const [ticket, setTicket] = useState(0);
    const [inPing, setInPing] = useState(false);
    const [sentCount, setSentCount] = useState(0);
    const [recvCount, setRecvCount] = useState(0);
    const [minRtt, setMinRtt] = useState<number | null>(null);
    const [maxRtt, setMaxRtt] = useState<number | null>(null);
    const [totalRtt, setTotalRtt] = useState<number | null>(null);

    const runPing = async () => {
        if (inPing == false) {
            return;
        }
        const api = getIcmpApi();
        try {
            setSentCount(value => value + 1);
            const res = await api.icmpPingPost({
                icmpPingPostRequest: {
                    token: getToken(),
                    addr: hostName,
                    pkgSize,
                },
            });
            if (res.success === true) {
                setRecvCount(value => value + 1);
                if (minRtt == null || maxRtt == null || totalRtt == null) {
                    setMinRtt(res.rtt ?? 0);
                    setMaxRtt(res.rtt ?? 0);
                    setTotalRtt(res.rtt ?? 0);
                } else {
                    setTotalRtt(value => (value ?? 0) + (res.rtt ?? 0));
                    if (res.rtt !== undefined && res.rtt < minRtt) {
                        setMinRtt(res.rtt);
                    }
                    if (res.rtt !== undefined && res.rtt > maxRtt) {
                        setMaxRtt(res.rtt);
                    }
                }
            }
        } catch (e) {
            console.log(e)
        }
    };

    useEffect(() => {
        const c = setInterval(() => {
            setTicket(value => value + 1);
        }, 1000);
        return () => { clearInterval(c) }
    }, []);

    useEffect(() => {
        runPing();
    }, [ticket]);

    return (
        <Card bordered={false} bodyStyle={{ height: "calc(100vh - 120px)", overflowY: "auto" }}
            extra={
                <Form layout="inline">
                    <Form.Item label="网络地址">
                        <Input value={tmpHostName} onChange={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            setTmpHostName(e.target.value.trim());
                        }} disabled={inPing} />
                    </Form.Item>
                    <Form.Item label="包大小">
                        <InputNumber value={pkgSize} controls={false} disabled={inPing}
                            min={20} max={1024} precision={0} onChange={value => setPkgSize(value as number)} />
                    </Form.Item>
                    <Form.Item>
                        {inPing == false && (
                            <Button type="primary" onClick={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setSentCount(0);
                                setRecvCount(0);
                                setInPing(true);
                                setMinRtt(null);
                                setMaxRtt(null);
                                setTotalRtt(null);
                                setHostName(tmpHostName);
                                setInPing(true);
                            }}>ping</Button>
                        )}
                        {inPing == true && (
                            <Button onClick={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setInPing(false);
                            }}>停止</Button>
                        )}
                    </Form.Item>
                </Form>}>
            {minRtt != null && maxRtt != null && totalRtt != null && (
                <Descriptions bordered={true}>
                    <Descriptions.Item label="目标地址">{hostName}</Descriptions.Item>
                    <Descriptions.Item label="发包数量">{sentCount}</Descriptions.Item>
                    <Descriptions.Item label="回包数量">{recvCount}</Descriptions.Item>
                    <Descriptions.Item label="最低延迟">{minRtt}ms</Descriptions.Item>
                    <Descriptions.Item label="最高延迟">{maxRtt}ms</Descriptions.Item>
                    <Descriptions.Item label="平均延迟">{((totalRtt ?? 0) / recvCount).toFixed(0)}ms</Descriptions.Item>
                </Descriptions>
            )}
        </Card>
    );
}

export default PingPanel;